package vben.core.framework.security;

import vben.core.framework.cache.RedisHandler;
import vben.core.framework.security.authc.AuthcFailedHandler;
import vben.core.framework.security.authz.AuthzDeniedHandler;
import vben.core.framework.security.authz.JwtFilterAdapter;
import vben.core.framework.security.authz.JwtHandler;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;

//Spring Security的配置
@Configuration
@RequiredArgsConstructor
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //1.禁用JWT登录无关的相关功能
        http.headers().frameOptions().disable().and()
                .formLogin(AbstractHttpConfigurer::disable)
                .httpBasic(AbstractHttpConfigurer::disable)
                .csrf(AbstractHttpConfigurer::disable)
                .logout(AbstractHttpConfigurer::disable)
                .sessionManagement(sessionManagement -> sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS));

        //2.跨域处理
        http.cors();
//        http.cors(cors -> cors.configurationSource(corsConfigurationSource()));

        //3.启用JWT过滤器
        http.apply(securityConfigurerAdapter());

        //4.过滤器异常与授权失败处理
        http.exceptionHandling()
                .authenticationEntryPoint(authcFailedHandler)
                .accessDeniedHandler(authzDeniedHandler);

        //5.授权配置
        http.authorizeRequests(authorizeRequests -> authorizeRequests
                .antMatchers("/","/auth/**","/wsv/**","/ass/oss/main/show","/druid/**","/login","/autologin","/gen/**").permitAll()
                .antMatchers("/doc.html","/swagger-ui.html","/webjars/**","/swagger-resources/**","/v2/**","/v3/**").permitAll()
                .antMatchers("/index.html","/favicon.ico", "/assets/**", "/resource/**","/_app.config.js").permitAll()
//                .antMatchers("/index.html","/favicon.ico", "/assets/**", "/resource/**","/_app.config.js").permitAll()//放行静态资源
//                .antMatchers("/sys/**").hasRole("ADMIN")//sys开头的需要管理员权限
//                .antMatchers(HttpMethod.OPTIONS, "/**").permitAll()//放行OPTIONS请求
                .antMatchers("/**").access("@authzHandler.hasPermission(request, authentication)")//其他请求统一认证
//                .antMatchers("/getUserInfo").hasRole("xxx")
                .anyRequest().authenticated());



    }

    //<<-------------------------------2.跨域处理-------------------------------
//    @Bean
//    CorsConfigurationSource corsConfigurationSource() {
//        CorsConfiguration configuration = new CorsConfiguration();
//        //可限制域名
////        if (environment.acceptsProfiles(Profiles.of("dev"))) {
////            configuration.setAllowedOrigins(Collections.singletonList("http://localhost:3100"));
////        } else {
////            configuration.setAllowedOrigins(Collections.singletonList("http://zsvg.com"));
////        }
////        configuration.setAllowedOrigins(Collections.singletonList("http://localhost:3100"));
//        configuration.setAllowCredentials(true);
//        configuration.setAllowedOrigins(Collections.singletonList("*"));
//        configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS"));
//        configuration.setAllowedHeaders(Collections.singletonList("*"));
//        configuration.addExposedHeader("X-Authenticate");
//        configuration.setMaxAge(3600L);
////        configuration.addExposedHeader("Authorization");
//        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
//        source.registerCorsConfiguration("/**", configuration);
//        return source;
//    }
    //>>

    //<<-------------------------------3.启用JWT过滤器-------------------------------
    private final JwtHandler jwtHandler;

    private final RedisHandler redisHandler;

    //JwtFilter 如果通过@Component 注解注入，则web.ignoring().antMatchers 不起作用，还是会被拦截过滤
    private JwtFilterAdapter securityConfigurerAdapter() {
        return new JwtFilterAdapter(jwtHandler, redisHandler);
    }
    //>>

    //<<-------------------------------4.过滤器异常与授权失败处理-------------------------------
    private final AuthzDeniedHandler authzDeniedHandler;//解决认证过的用户访问无权限资源时的异常

    private final AuthcFailedHandler authcFailedHandler;//解决匿名用户访问无权限资源时的异常
    //>>

    //<<-------------------------------X.其他配置-------------------------------
    //配置security忽略的请求与资源 升级springboot 后不兼容，放上面
//    @Override
//    public void configure(WebSecurity web) {
//        web.ignoring().antMatchers("/","/auth/**","/wsv/**","/ass/oss/main/show","/druid/**","/login","/autologin");
//        //测试环境swagger放行
//        web.ignoring().antMatchers("/doc.html","/swagger-ui.html","/webjars/**","/swagger-resources/**","/v2/**","/v3/**");
//        //前端放在一起时放行前端UI
//        web.ignoring().antMatchers("/jquery.js","/sso.html","/index.html","/favicon.ico", "/assets/**", "/resource/**","/_app.config.js");
//    }



//    @Override
//    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//        auth.authenticationProvider(ssLoginProvider);
////        auth.userDetailsService(ssUserDetailsService).passwordEncoder( passwordEncoder());
//    }

//    @Bean
//    public PasswordEncoder passwordEncoder() {
//        return new BCryptPasswordEncoder();
//    }
    //authn是认证相关的类，authz是授权相关的类


}
